package edu.gduf.parcel.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * 
 * @author Joe
 * @Description 外卖数据源
 * @Date 2016年11月18日 下午11:49:17
 * @Since v1.0
 */
@Configuration
@MapperScan(basePackages = { ParcelDataSourceConfig.PACKAGE }, sqlSessionFactoryRef = "parcelSqlSessionFactory")
public class ParcelDataSourceConfig {

	static final String PACKAGE = "edu.gduf.parcel.repository";

	private static Logger logger = LoggerFactory.getLogger(ParcelDataSourceConfig.class);
	@Value("${parcel.datasource.driverClassName}")
	private String driverClassName = "com.mysql.jdbc.Driver";
	@Value("${parcel.datasource.url}")
	private String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=UTF8";
	@Value("${parcel.datasource.username}")
	private String username = "root";
	@Value("${parcel.datasource.password}")
	private String password = "root";
	@Value("${parcel.mybatis.mapperLocations}")
	private String mapperLocations = "classpath:mapper/*/*.xml";
	/*
	 * druid连接池属性开始
	 */
	@Value("${jdbc.pool.initialSize}")
	private int initialSize = 1;
	@Value("${jdbc.pool.maxActive}")
	private int maxActive = 20;
	@Value("${jdbc.pool.minIdle}")
	private int minIdle = 1;
	@Value("${jdbc.pool.maxWait}")
	private int maxWait;
	@Value("${jdbc.pool.timeBetweenEvictionRunsMillis}")
	private long timeBetweenEvictionRunsMillis = 60000;
	@Value("${jdbc.pool.minEvictableIdleTimeMillis}")
	private long minEvictableIdleTimeMillis = 300000;
	@Value("${jdbc.pool.testWhileIdle}")
	private boolean testWhileIdle = true;
	@Value("${jdbc.pool.testOnBorrow}")
	private boolean testOnBorrow = false;
	@Value("${jdbc.pool.testOnReturn}")
	private boolean testOnReturn = false;
	@Value("${jdbc.pool.poolPreparedStatements}")
	private boolean poolPreparedStatements = false;
	@Value("${jdbc.pool.maxOpenPreparedStatements}")
	private int maxOpenPreparedStatements = 20;
	@Value("${jdbc.pool.filters}")
	private String filters = "stat,log4j";
	@Value("${jdbc.pool.connectionProperties}")
	private String connectionProperties = "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000";
	/*
	 * druid连接池属性结束
	 */

	/**
	 * 配置数据源
	 * 
	 * @return
	 */
	@Bean("parcelDataSource")
	public DataSource parcelDataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(jdbcUrl);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		dataSource.setInitialSize(initialSize);
		dataSource.setMaxActive(maxActive);
		dataSource.setMinIdle(minIdle);
		dataSource.setMaxWait(maxWait);
		dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
		dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
		dataSource.setTestWhileIdle(testWhileIdle);
		dataSource.setTestOnBorrow(testOnBorrow);
		dataSource.setTestOnReturn(testOnReturn);
		dataSource.setPoolPreparedStatements(poolPreparedStatements);
		dataSource.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
		dataSource.setConnectionProperties(connectionProperties);
		try {
			dataSource.setFilters(filters);
		} catch (SQLException e) {
			logger.error("配置数据库连接属性出错", e);
		}
		return dataSource;
	}

	/**
	 * 配置事务管理器
	 * 
	 * @param parcelDataSource
	 * @return
	 */
	@Bean("parcelTransactionManager")
	public DataSourceTransactionManager parcelTransactionManager(
			@Qualifier("parcelDataSource") DataSource parcelDataSource) {
		return new DataSourceTransactionManager(parcelDataSource);

	}

	/**
	 * 配置MyBatis SqlSessionFacotry
	 * 
	 * @param parcelDataSource
	 * @return
	 * @throws Exception
	 */
	@Bean("parcelSqlSessionFactory")
	public SqlSessionFactory parcelSqlSessionFactory(@Qualifier("parcelDataSource") DataSource parcelDataSource)
			throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(parcelDataSource);
		sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
		return sessionFactory.getObject();
	}
}
